home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
gfx
/
conv
/
ilbm24.lha
/
ilbm
/
readsunras.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-02-12
|
7KB
|
294 lines
/*
*
* This function almost taken wholesale from the xv2.21 distribution.
*
* Slight modifications by Brett Van Sprewenburg
* For relevant information on the xv disturbtion, get the xv display kit.
*
* Altered some return codes to return < 0 on error.
*
* LoadSunRas(fname) - loads a Raster pic
*
*/
#include <writeilbm.h>
static int SunRasError();
static void SunRas1to8();
static int rle_read();
static void flipl();
static void fixBGR();
byte *pic, r[256], g[256], b[256];
int pHIGH,pWIDE;
int LoadSunRas(char *fname)
{
FILE *fp;
int linesize,lsize,csize,isize,flipit,i,w,h,d,rv;
byte *image, *line;
rv = 0;
/* read in the Sun Rasterfile picture */
fp=fopen(fname,"r");
if (!fp) return( SunRasError("unable to open file") );
flipit = FALSE;
fread(&sunheader,sizeof(struct RasterHeader),1,fp);
if (sunheader.ras_magic != RAS_MAGIC)
{
flipl( (byte *) &sunheader.ras_magic);
if (sunheader.ras_magic == RAS_MAGIC) flipit = TRUE;
else flipl( (byte *) &sunheader.ras_magic);
}
if (sunheader.ras_magic != RAS_MAGIC) {
fprintf(stderr,"'%s' is not a Sun Raster file. Exiting.\n",fname);
fclose(fp);
return -1;
}
if (flipit) {
flipl((byte *) &sunheader.ras_width);
flipl((byte *) &sunheader.ras_height);
flipl((byte *) &sunheader.ras_depth);
flipl((byte *) &sunheader.ras_length);
flipl((byte *) &sunheader.ras_type);
flipl((byte *) &sunheader.ras_maptype);
flipl((byte *) &sunheader.ras_maplength);
}
/* make sure that the input picture can be dealt with */
if ( sunheader.ras_depth != 1 &&
sunheader.ras_depth != 8 &&
sunheader.ras_depth != 24 &&
sunheader.ras_depth != 32) {
fprintf (stderr, "Sun rasterfile image has depth %d\n",
sunheader.ras_depth);
fprintf (stderr, "Depths supported are 1, 8, 24, and 32\n");
return -1;
}
if (sunheader.ras_type != RT_OLD &&
sunheader.ras_type != RT_STANDARD &&
sunheader.ras_type != RT_BYTE_ENCODED &&
sunheader.ras_type != RT_FORMAT_RGB) {
fprintf (stderr, "Sun rasterfile of unsupported type %d\n",
sunheader.ras_type);
return -1;
}
if (sunheader.ras_maptype != RMT_RAW &&
sunheader.ras_maptype != RMT_NONE &&
sunheader.ras_maptype != RMT_EQUAL_RGB) {
fprintf (stderr, "Sun rasterfile colormap of unsupported type %d\n",
sunheader.ras_maptype);
return -1;
}
w = sunheader.ras_width;
h = sunheader.ras_height;
d = sunheader.ras_depth;
isize = sunheader.ras_length ?
sunheader.ras_length :
(w * h * d) / 8;
csize = (sunheader.ras_maptype == RMT_NONE) ? 0 : sunheader.ras_maplength;
lsize = w * h;
if (d == 24 || d == 32) lsize = lsize * 3;
linesize = w * d;
/* if ((linesize % 48) && d == 24) linesize += (48 - (linesize % 48)); */
if (linesize % 16) linesize += (16 - (linesize % 16));
linesize /= 8;
if (DEBUG)
{
fprintf(stderr,"readsunras: LoadSunRas() - loading a %dx%d pic, %d planes\n",
w, h,
d);
fprintf (stderr,
"type %d, maptype %d, isize %d, csize %d, lsize %d, linesize %d\n",
sunheader.ras_type, sunheader.ras_maptype,
isize, csize, lsize, linesize);
}
fprintf(stderr,"%dx%d Sun %s rasterfile. (%d plane%s) (%d uncompressed bytes)\n",
sunheader.ras_width, sunheader.ras_height,
sunheader.ras_type == RT_BYTE_ENCODED ? "rle" : "standard",
d,
d == 1 ? "" : "s",
sizeof (struct RasterHeader) + csize + isize);
/* read in the colormap, if any */
if (sunheader.ras_maptype == RMT_EQUAL_RGB && csize)
{
fread (r, sizeof (byte), sunheader.ras_maplength/3, fp);
fread (g, sizeof (byte), sunheader.ras_maplength/3, fp);
fread (b, sizeof (byte), sunheader.ras_maplength/3, fp);
}
else if (sunheader.ras_maptype == RMT_RAW && csize)
{
/* we don't know how to handle raw colormap, ignore */
fseek (fp, (long) csize, 1);
}
else { /* no colormap, make one up */
if (sunheader.ras_depth == 1) {
r[0] = g[0] = b[0] = 0;
r[1] = g[1] = b[1] = 255;
}
else if (sunheader.ras_depth == 8) {
for (i = 0; i < 256; i++)
r[i] = g[i] = b[i] = i;
}
}
/* allocate memory for picture and read it in */
/* note we may slightly overallocate here (if image is padded) */
image = (byte *) malloc (lsize);
line = (byte *) malloc (linesize);
if (image == NULL || line == NULL)
fprintf(stderr,"Can't allocate memory for image\n");
for (i = 0; i < h; i++) {
if (sunheader.ras_type == RT_BYTE_ENCODED) {
if (rle_read (line, 1, linesize, fp, (i==0)) != linesize) break;
return (SunRasError ("rle file read error"));
}
else {
if (fread (line, 1, linesize, fp) != linesize)
return (SunRasError ("file read error"));
}
switch (d) {
case 1: SunRas1to8 (image + w * i, line, w); break;
case 8: memcpy (image + w * i, line, w); break;
case 24: memcpy (image + w * i * 3, line, w * 3); break;
case 32: {
int k;
byte *ip, *op;
ip = line;
op = (byte *) (image + w * i * 3);
for (k = 0; k<w; k++) {
*ip++; /* skip 'alpha' */
*op++ = *ip++; /* red */
*op++ = *ip++; /* green */
*op++ = *ip++; /* blue */
}
}
}
}
if (fp != stdin) fclose (fp);
if (DEBUG) fprintf(stderr,"Sun ras: image loaded!\n");
if (d == 24 || d == 32)
if (sunheader.ras_type != RT_FORMAT_RGB) fixBGR(image,w,h);
pic = image;
pWIDE = w;
pHIGH = h;
return 0;
}
/*****************************/
static int rle_read (ptr, size, nitems, fp, init)
byte *ptr;
int size, nitems,init;
FILE *fp;
{
static int count, ch;
int readbytes, c, read;
if (init) { count = ch = 0; }
readbytes = size * nitems;
for (read = 0; read < readbytes; read++) {
if (count) {
*ptr++ = (byte) ch;
count--;
}
else {
c = getc(fp);
if (c == EOF) break;
if (c == RAS_RLE) { /* 0x80 */
count = getc(fp);
if (count == EOF) break;
if (count < 0) count &= 0xff;
if (count == 0) *ptr++ = c;
else {
if ((ch = getc(fp)) == EOF) break;
*ptr++ = ch;
}
}
else *ptr++ = c;
}
}
return (read/size);
}
/*****************************/
static int SunRasError(st)
char *st;
{
fprintf(stderr,"LoadSunRas() - %s",st);
return -1;
}
/*****************************/
static void SunRas1to8 (dest, src, len)
byte *dest, *src;
int len;
{
int i, b;
int c;
for (i = 0, b = -1; i < len; i++) {
if (b < 0) {
b = 7;
c = ~*src++;
}
*dest++ = ((c >> (b--)) & 1);
}
}
/*****************************/
static void flipl(p)
byte *p;
{
byte t;
t = p[0]; p[0]=p[3]; p[3] = t;
t = p[1]; p[1]=p[2]; p[2] = t;
}
/* kr3 - fix up BGR order SUN 24-bit rasters to be RGB order */
static void fixBGR(img,w,h)
unsigned char *img;
int w,h;
{
int i,npixels;
unsigned char tmp;
npixels = w*h;
for (i=0; i<npixels; i++) {
tmp = img[0]; /* swap red and blue channels */
img[0] = img[2];
img[2] = tmp;
img += 3; /* bump to next pixel */
}
}